package com.ffr.utils;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.util.concurrent.*;

/**
 * @author hkn
 * @描述 SpringBoot多线程工具类提供常用的多线程操作方法
 * @date 2024/10/21 13:48
 */
@Component
public class ThreadPoolUtil {
    private final ThreadPoolTaskExecutor executor;

    /**
     * 构造函数，初始化线程池
     */
    public ThreadPoolUtil() {
        this.executor = new ThreadPoolTaskExecutor();
        this.executor.setCorePoolSize(5);  // 设置核心线程数
        this.executor.setMaxPoolSize(10);  // 设置最大线程数
        this.executor.setQueueCapacity(25);  // 设置队列容量
        this.executor.setThreadNamePrefix("MyThreadPool-");  // 设置线程名称前缀
        this.executor.initialize();  // 初始化线程池
    }

    /**
     * 执行无返回值的任务
     * @param task 要执行的任务
     */
    public void executeTask(Runnable task) {
        executor.execute(task);
    }

    /**
     * 提交有返回值的任务
     * @param task 要执行的任务
     * @return CompletableFuture对象，可用于获取任务结果
     */
    public <T> CompletableFuture<T> submitTask(java.util.concurrent.Callable<T> task) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                return task.call();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }, executor);
    }

    /**
     * 使用固定大小的线程池执行多个任务
     * @param nThreads 线程池大小
     * @param tasks 要执行的任务列表
     */
    public void executeWithFixedThreadPool(int nThreads, Runnable... tasks) {
        ThreadPoolExecutor fixedThreadPool = new ThreadPoolExecutor(
                nThreads,                // 核心线程数
                nThreads,                // 最大线程数
                0L, TimeUnit.MILLISECONDS, // 空闲线程的存活时间
                new LinkedBlockingQueue<>(), // 使用无界队列存储任务
                new ThreadFactory() {       // 手动创建线程工厂
                    private int counter = 0;

                    @Override
                    public Thread newThread(Runnable r) {
                        return new Thread(r, "CustomThread-" + counter++);
                    }
                }
        );
        for (Runnable task : tasks) {
            fixedThreadPool.execute(task);
        }
        shutdownAndAwaitTermination(fixedThreadPool);
    }

    /**
     * 关闭线程池并等待任务完成
     * @param pool 要关闭的线程池
     */
    private void shutdownAndAwaitTermination(ExecutorService pool) {
        pool.shutdown();  // 禁止提交新任务
        try {
            // 等待现有任务完成
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                pool.shutdownNow();  // 取消当前执行的任务
                // 等待任务响应中断
                if (!pool.awaitTermination(60, TimeUnit.SECONDS)){
                    System.err.println("线程池未能终止");
                }

            }
        } catch (InterruptedException ie) {
            // 如果当前线程也被中断，则重新取消
            pool.shutdownNow();
            // 保留中断状态
            Thread.currentThread().interrupt();
        }
    }
}
